package com.lyb.hardware.disk;

import com.lyb.Utils;
import com.lyb.constant.DiskConstant;

import java.nio.ByteBuffer;
import java.util.Arrays;

import com.lyb.constant.SystemConstant;

/**
 * 目录项类
 *
 * @author Mr.Alpaca
 * @version 1.4.0
 */
public class DirectoryEntry {
    /**
     * 目录项，8字节数组，各索引表示的内容如下
     * 0 1 2         3          4          5 6           7
     * 文件/目录名 文件/目录类型 文件/目录权限 文件/目录长度 文件/目录起始磁盘号
     */
    private byte[] directoryEntry;
    /**
     * 文件/目录名
     */
    private String name;
    /**
     * 文件/目录类型
     * "e"：可执行文件
     * " "：目录
     * 其他单字母：普通文件
     */
    private String type;
    /**
     * 文件/目录属性(权限)
     * "r"：只读
     * "w"：可读写
     * "n"：不准查看
     */
    private String property;
    /**
     * 文件/目录长度(字节)
     * 文件：(0, 128 x 64](假设所有磁块都只存储内容)
     * 目录：0
     */
    private int length;
    /**
     * 文件/目录起始磁盘号
     */
    private byte startDiskNum;

    public DirectoryEntry() {
    }

    /**
     * 根据传入名和类型构建对象，属性默认为可读写
     *
     * @param name 文件/目录名
     * @param type 文件/目录类型
     */
    public DirectoryEntry(String name, String type) {
        this.name = name;
        this.type = type;
        this.property = SystemConstant.FILE_WRITE;
    }

    /**
     * 构造函数
     * 根据传入字节数目录项构建对象
     *
     * @param directoryEntry 目录项
     */
    public DirectoryEntry(byte[] directoryEntry) {
        this.directoryEntry = directoryEntry;

        /* 解析目录项并赋予对象对应属性值 */
        parseDirectoryEntry(this.directoryEntry);
    }

    /**
     * 构造函数
     * 根据传入属性构建对象
     *
     * @param name         文件/目录名
     * @param type         文件/目录类型
     * @param property     文件/目录属性
     * @param length       文件/目录长度
     * @param startDiskNum 文件/目录起始磁盘号
     */
    public DirectoryEntry(String name, String type, String property, int length, byte startDiskNum) {
        this.name = name;
        this.type = type;
        this.property = property;
        this.length = length;
        this.startDiskNum = startDiskNum;

        /* 将传入属性按指定格式转换并赋予目录项 */
        setDirectoryEntry();
    }

    /**
     * 将传入目录项解析并赋予对象对应属性值
     *
     * @param directoryEntry 目录项
     */
    public void parseDirectoryEntry(byte[] directoryEntry) {
        this.name = new String(Arrays.copyOfRange(directoryEntry, 0, 3));
        this.type = new String(Arrays.copyOfRange(directoryEntry, 3, 4));
        this.property = new String(Arrays.copyOfRange(directoryEntry, 4, 5));
        this.length = Utils.byteArrayToInt(Arrays.copyOfRange(directoryEntry, 5, 7));
        this.startDiskNum = directoryEntry[7];
    }

    /**
     * 重写方法，将对象属性按指定格式转换并赋予目录项
     */
    public void setDirectoryEntry() {
        /* 为缓冲分配 8 字节的空间 */
        ByteBuffer buffer = ByteBuffer.allocate(DiskConstant.DIRECTORY_ENTRY_LENGTH);

        /* 往缓冲中添加各属性 */
        buffer.put(name.getBytes());
        buffer.put(type.getBytes());
        buffer.put(property.getBytes());
        buffer.put(Utils.intToByteArray(length));
        buffer.put(startDiskNum);

        /* 获取目录项(byte 数组) */
        this.directoryEntry = buffer.array();
    }


    /* ********** Getter & Setter ********** */

    public byte[] getDirectoryEntry() {
        return directoryEntry;
    }

    public String getName() {
        return name;
    }

    public String getType() {
        return type;
    }

    public String getProperty() {
        return property;
    }

    public void setProperty(String property) {
        this.property = property;
    }

    public int getLength() {
        return length;
    }

    public void setLength(int length) {
        this.length = length;
    }

    public byte getStartDiskNum() {
        return startDiskNum;
    }

    public void setStartDiskNum(byte startDiskNum) {
        this.startDiskNum = startDiskNum;
    }
}
